﻿
//+++++++++++++++++++++++++++++++++++++++++++++++++++
//2012.3.31
//  141行, 用if语句忽略空指令;



//汇编运算转化器
namespace n_Macro
{
using System;
using System.Text;

using n_AddressList;
using n_Config;
using n_ConstExpression;
using n_CPUType;
using n_FunctionList;
using n_Interrupt;
using n_MemberType;
using n_VarType;
using n_VdataList;
using n_VarList;
using n_ET;
using i_Compiler;
using n_OS;
using n_CDebug;

public static class Macro
{
	//编译器启动初始化,加载汇编运算库文件
	public static void LoadFile()
	{
		//加载运算信息表
		MCS51_Lib = LibStandard( Compiler.OpenCompileFile( n_Config.Config.Path_compiler + "CPU" + OS.PATH_S + "MCS51" + OS.PATH_S + "asmoper.lst" ) );
		ATMEGA_Lib = LibStandard( Compiler.OpenCompileFile( n_Config.Config.Path_compiler + "CPU" + OS.PATH_S + "ATMEGA" + OS.PATH_S + "asmoper.lst" ) );
		SPCE061A_Lib = LibStandard( Compiler.OpenCompileFile( n_Config.Config.Path_compiler + "CPU" + OS.PATH_S + "SPCE061A" + OS.PATH_S + "asmoper.lst" ) );
		CORTEX_M0_Lib = LibStandard( Compiler.OpenCompileFile( n_Config.Config.Path_compiler + "CPU" + OS.PATH_S + "CORTEX M0" + OS.PATH_S + "asmoper.lst" ) );
		//PC80X86_Lib = LibStandard( Compiler.OpenCompileFile( n_Config.Config.Path_compiler + "CPU" + OS.PATH_S + "PC80X86" + OS.PATH_S + "asmoper.lst" ) );
		PC80X86_Lib = null;
		VM_Lib = LibStandard( Compiler.OpenCompileFile( n_Config.Config.Path_compiler + "CPU" + OS.PATH_S + "VM" + OS.PATH_S + "asmoper.lst" ) );
	}
	
	//展开宏指令为目标代码
	public static string[] DeployMacro( string[] Source )
	{
		//检查所有变量是否有互锁冲突
		int mulerr = VarList.GetLockError();
		if( Config.DealLockError && mulerr != -1 ) {
			n_VarNode.VarNode v = VarList.Get( mulerr );
			ET.WriteParseError( v.Location, "变量 <" +v.Name + "> 发生了多线程访问冲突, 请增加互锁块" );
		}
		
		string[] ChipList = new string[ Config.ChipNumber ];
		for( int i = 0; i < Source.Length; ++i ) {
			Config.SetChipIndex( i );
			ChipList[ i ] = DeployOnceMacro( Source[ i ] );
		}
		return ChipList;
	}
	
	//展开宏指令为目标代码
	public static string DeployOnceMacro( string Source )
	{
		int LabelIndex = 0;  //独立的标号索引
		StringBuilder Result = new StringBuilder( "" );  //字符串容器
		//当前宏指令的展开结果
		StringBuilder instruction = new StringBuilder( "" );
		string[] Cut = Source.TrimEnd( '\n' ).Split( '\n' );
		
		//选择目标cpu运算库
		Lib = SelectLib();
		
		//遍历宏指令序列
		for( int i = 0; i < Cut.Length; ++i ) {
			
			string[] Sence = Cut[ i ].Split( ' ' );
			
			//如果是调用PC的DLL函数 直接用原函数名代替 (2016.5.6 改为了 引用信息, 不用函数名字符串)
			if( Cut[ i ].StartsWith( "函数调用 " ) ) {
				int FuncIndex = int.Parse( Sence[ 1 ] );
				if( FunctionList.Get( FuncIndex ).InterType == MemberType.FunctionType.Interface ) {
					string RefValue = FunctionList.Get( FuncIndex ).RefValue;
					//FunctionName = FunctionName.Remove( 0, FunctionName.LastIndexOf( "." ) + 1 );
					Result.Append( n_VCODE.C.接口调用 + " " + RefValue );
					Result.Append( "\n" );
					continue;
				}
				else {
					Cut[ i ] = n_VCODE.C.函数调用 + " " + Config.PreLabel.Function + Sence[ 1 ];
				}
			}
			//如果是内嵌汇编, 跳过搜索
			if( Cut[ i ].StartsWith( "内嵌汇编 " ) ) {
				Result.Append( Cut[ i ].Remove( 0, 5 ) );
				Result.Append( "\n" );
				continue;
			}
			//如果是系统标志, 跳过搜索
			if( Cut[ i ].StartsWith( "系统标志 " ) ) {
				string Name = Cut[ i ].Split( ' ' )[ 1 ];
				Debug.Deal( Name );
				continue;
			}
			//判断是否设置堆栈指令(中断函数中)
			if( Cut[ i ].StartsWith( "设置堆栈 " ) ) {
				int BaseVdataIndex = VdataList.GetIndex( VarType.VBase );
				int StartAddr = AddressList.StaticMaxAddr[ BaseVdataIndex ] + Interrupt.GetStackNumber() + 1;
				int FuncIndex = int.Parse( Sence[ 1 ] );
				
				/*
				 * 旧版本的中断函数空间分配
				int Length = 
					AddressList.MaxUsedAddressList[ BaseVdataIndex ][ FuncIndex ] -
					VdataList.Get( BaseVdataIndex ).StartAddress;
				if( Length < 0 ) {
					Length = 0;
				}
				else {
					++Length;
				}
				//每个中断函数可能调用其它函数, 所以预留100个字节堆栈
				//不调用其他函数时可以去掉的
				Length += Interrupt.StaceSize;
				*/
				
				int Length = 50;
				int SetLength = FunctionList.Get( FuncIndex ).InterruptSpaceNumber;
				if( SetLength != -1 ) {
					Length = SetLength;
				}
				
				Interrupt.AddStackNumber( Length );
				Cut[ i ] = Sence[ 0 ] + " " + StartAddr + " " + ( Length - 1 );
			}
			//判断是否转移形参
			if( Cut[ i ].StartsWith( "转移形参 " ) ) {
				int FuncIndex = int.Parse( Sence[ 1 ] );
				int Length = FunctionList.Get( FuncIndex ).VarSize;
				if( Length == 0 ) {
					continue;
				}
				Cut[ i ] = Sence[ 0 ] + " " + Length;
			}
			//判断是否为堆栈操作指令
			if( Cut[ i ].StartsWith( "堆栈递增 " ) || Cut[ i ].StartsWith( "堆栈递减 " ) ) {
				int FuncIndex = int.Parse( Sence[ 1 ] );
				int BaseVdataIndex = VdataList.GetIndex( VarType.VBase );
				int Length = 
					AddressList.MaxUsedAddressList[ BaseVdataIndex ][ FuncIndex ] -
					VdataList.Get( BaseVdataIndex ).StartAddress;
				if( Length < 0 ) {
					Length = 0;
				}
				else {
					++Length;
				}
				int mod = Length % 4;
				if( mod != 0 ) {
					Length += 4 - mod;
				}
				Cut[ i ] = Sence[ 0 ] + " " + Length;
			}
			//判断是否为保护接口指令
			if( Cut[ i ] == "保护接口实参" || Cut[ i ] == "恢复接口实参" ) {
				Cut[ i ] = Cut[ i ] + " " + Interrupt.StartAddrOfBaseCode;
			}
			
			//!!!!!!!!!!!!!!暂时无效
			//判断是否为函数尺寸
			if( Cut[ i ].StartsWith( "函数尺寸_" ) ) {
				int VarAddr = int.Parse( Sence[ 1 ] );
				int FuncIndex = int.Parse( Sence[ 2 ] );
				string SType = Sence[ 0 ].Split( '_' )[ 1 ];
				
				int BaseVdataIndex = VdataList.GetIndex( VarType.VBase );
				int Length = 
					AddressList.MaxUsedAddressList[ BaseVdataIndex ][ FuncIndex ] -
					VdataList.Get( BaseVdataIndex ).StartAddress + 1;
				
				
				Cut[ i ] = "常量赋值_" + SType + " " + VarAddr + " " + Length + " temp";
			}
			//从第2项起是实参序列
			Sence = Cut[ i ].Split( ' ' );
			
			//匹配宏指令的目标指令序列
			string[] asm = GetRule( Sence[ 0 ] ).TrimEnd( '\n' ).Split( '\n' );
			
			//如果没有指令,继续解析下一指令
			if( asm.Length == 1 ) {
				continue;
			}
			//从第3项起是形参序列
			string[] word = asm[ 0 ].Split( ' ' );
			
			//当前宏指令的展开结果
			instruction.Length = 0;
			
			string l_label = "l" + LabelIndex + "_";
			
			//替换标号和形参
			for( int n = 1; n < asm.Length; ++n ) {
				for( int j = 2; j < word.Length; ++j ) {
					asm[ n ] = asm[ n ].Replace( word[ j ], Sence[ j - 1 ] );
				}
				asm[ n ] = asm[ n ].Replace( "@label", l_label );
				
				instruction.Append( asm[ n ] );
				instruction.Append( "\n" );
			}
			//计算序列中的常量表达式
			++LabelIndex;
			
			Result.Append( ";------------------------- " + Cut[ i ] + "\n" );
			Result.Append( ConstExpression.Expression( instruction.ToString() ) );
		}
		return Result.ToString();
	}
	
	//读取目标cpu运算库
	static string[] LibStandard( string Lib )
	{
		Lib = Lib.Remove( Lib.IndexOf( "\n<end>" ) );
		Lib = Lib.Replace( '\t', ' ' );
		string[] Lines = Lib.Split( '\n' );
		string[] Temp = new string[ Lines.Length ];
		int j = 0;
		for( int i = 0; i < Lines.Length; ++i ) {
			int NoteIndex = Lines[ i ].IndexOf( "//" );
			if( NoteIndex != -1 ) {
			   	Lines[ i ] = Lines[ i ].Remove( NoteIndex );
			}
			if( Lines[ i ].Trim( ' ' ) == "" ) {
				continue;
			}
			Temp[ j ] = Lines[ i ];
			++j;
		}
		//去除无效的行
		string[] LibCut = new string[ j ];
		for( int i = 0; i < j; ++i ) {
			LibCut[ i ] = Temp[ i ];
		}
		return LibCut;
	}
	
	//获取一个汇编运算的转化规则
	static string GetRule( string Name )
	{
		for( int i = 0; i < Lib.Length; ++i ) {
			
			//如果不是对应的宏指令标志, 跳过
			if( !Lib[ i ].StartsWith( "# " ) || Lib[ i ].Split( ' ' )[ 1 ] != Name ) {
				continue;
			}
			//获取完整的目标指令序列
			for( int j = i + 1; j < Lib.Length; ++j ) {
				if( Lib[ j ].StartsWith( "# " ) ) {
					string Result = "";
					for( int k = i; k < j; ++k ) {
						Result += Lib[ k ] + "\n";
					}
					return Result;
				}
			}
		}
		ET.ShowError( "未知的汇编运算定义:" + Name );
		return null;
	}
	
	//选择目标cpu运算库
	static string[] SelectLib()
	{
		string cpu = Config.GetCPU();
		if( cpu.StartsWith( CPUType.MEGA_X ) ) {
			return ATMEGA_Lib;
		}
		if( cpu.StartsWith( CPUType.MCS_X ) ) {
			return MCS51_Lib;
		}
		switch( cpu ) {
			case CPUType.SPCE061A: 		return SPCE061A_Lib;
			case CPUType.LPC1114: 		return CORTEX_M0_Lib;
			case CPUType.PC80X86: 		return PC80X86_Lib;
			case CPUType.VM: 			return VM_Lib;
			default: ET.ShowError( "未知的芯片类型: " + Config.GetCPU() ); return null;
		}
	}
	
	static string[] MCS51_Lib;
	static string[] ATMEGA_Lib;
	static string[] SPCE061A_Lib;
	static string[] CORTEX_M0_Lib;
	static string[] PC80X86_Lib;
	static string[] VM_Lib;
	static string[] Lib;
}
}

